home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb.new / gdb-3.98 / bfd.mips / bout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-23  |  21.9 KB  |  760 lines

  1. /* BFD back-end for Intel 960 b.out binaries.
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Written by Cygnus Support.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* $Id: bout.c,v 1.9 1991/07/31 16:57:28 gnu Exp $ */
  22.  
  23. #include <sysdep.h>
  24. #include "bfd.h"
  25. #include "libbfd.h"
  26.  
  27. #include "bout.h"
  28.  
  29. #include "stab.gnu.h"
  30. #include "libaout.h"        /* BFD a.out internal data structures */
  31.  
  32. /* Align an address by rounding it up to a power of two.  It leaves the
  33.    address unchanged if align == 0 (2^0 = alignment of 1 byte) */
  34. #define    i960_align(addr, align)    \
  35.     ( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
  36.  
  37.  
  38.  
  39. PROTO (static boolean, b_out_squirt_out_relocs,(bfd *abfd, asection *section));
  40. PROTO (static bfd_target *, b_out_callback, (bfd *));
  41.  
  42. PROTO (boolean, aout_32_slurp_symbol_table, (bfd *abfd));
  43. PROTO (void , aout_32_write_syms, ());
  44.  
  45. PROTO (static void, swap_exec_header, (bfd *abfd, struct internal_exec *execp));
  46.  
  47.  
  48. static bfd_target *
  49. b_out_little_object_p (abfd)
  50.      bfd *abfd;
  51. {
  52.   unsigned char magicbytes[LONG_SIZE];
  53.   struct internal_exec anexec;
  54.   
  55.   if (bfd_read ((PTR)magicbytes, 1, LONG_SIZE, abfd) != LONG_SIZE) {
  56.     bfd_error = system_call_error;
  57.     return 0;
  58.   }
  59.   anexec.a_magic = _do_getl32 (magicbytes);
  60.  
  61.   if (N_BADMAG (anexec)) {
  62.     bfd_error = wrong_format;
  63.     return 0;
  64.   }
  65.   return aout_32_some_aout_object_p (abfd, b_out_callback);
  66. }
  67.  
  68. static bfd_target *
  69. b_out_big_object_p (abfd)
  70.      bfd *abfd;
  71. {
  72.   unsigned char magicbytes[LONG_SIZE];
  73.   struct internal_exec anexec;
  74.  
  75.   if (bfd_read ((PTR)magicbytes, 1, LONG_SIZE, abfd) != LONG_SIZE) {
  76.     bfd_error = system_call_error;
  77.     return 0;
  78.   }
  79.  
  80.   anexec.a_magic = _do_getb32 (magicbytes);
  81.  
  82.   if (N_BADMAG (anexec)) {
  83.     bfd_error = wrong_format;
  84.     return 0;
  85.   }
  86.   return aout_32_some_aout_object_p (abfd, b_out_callback);
  87. }
  88.  
  89. /* Finish up the opening of a b.out file for reading.  Fill in all the
  90.    fields that are not handled by common code.  */
  91.  
  92. static bfd_target *
  93. b_out_callback (abfd)
  94.      bfd *abfd;
  95. {
  96.   struct internal_exec anexec;
  97.   struct internal_exec *execp = &anexec;
  98.   unsigned long bss_start;
  99.  
  100.   /* Reread the exec header, because the common code didn't get all of
  101.      our extended header.  */
  102.  
  103.   if (bfd_seek (abfd, 0L, SEEK_SET) < 0) {
  104.     bfd_error = system_call_error;
  105.     return 0;
  106.   }
  107.  
  108.   /* FIXME, needs to be hacked for character array read-in ala sunos.c.  */
  109.   if (bfd_read ((PTR) execp, 1, sizeof (struct internal_exec), abfd)
  110.       != sizeof (struct internal_exec)) {
  111.     bfd_error = wrong_format;
  112.     return 0;
  113.   }
  114.  
  115.   swap_exec_header (abfd, execp);
  116.  
  117.   /* Architecture and machine type */
  118.   abfd->obj_arch = bfd_arch_i960;    /* B.out only used on i960 */
  119.   abfd->obj_machine = bfd_mach_i960_core;    /* Default */
  120. /* FIXME:  Set real machine type from file here */
  121.  
  122.   /* The positions of the string table and symbol table.  */
  123.   obj_str_filepos (abfd) = N_STROFF (anexec);
  124.   obj_sym_filepos (abfd) = N_SYMOFF (anexec);
  125.  
  126.   /* The alignments of the sections */
  127.   obj_textsec (abfd)->alignment_power = execp->a_talign;
  128.   obj_datasec (abfd)->alignment_power = execp->a_dalign;
  129.   obj_bsssec  (abfd)->alignment_power = execp->a_balign;
  130.  
  131.   /* The starting addresses of the sections.  */
  132.   obj_textsec (abfd)->vma = anexec.a_tload;
  133.   obj_datasec (abfd)->vma = anexec.a_dload;
  134.   bss_start = anexec.a_dload + anexec.a_data; /* BSS = end of data section */
  135.   obj_bsssec (abfd)->vma = i960_align (bss_start, anexec.a_balign);
  136.  
  137.   /* The file positions of the sections */
  138.   obj_textsec (abfd)->filepos = N_TXTOFF(anexec);
  139.   obj_datasec (abfd)->filepos = N_DATOFF(anexec);
  140.  
  141.   /* The file positions of the relocation info */
  142.   obj_textsec (abfd)->rel_filepos = N_TROFF(anexec);
  143.   obj_datasec (abfd)->rel_filepos =  N_DROFF(anexec);
  144.  
  145.   return abfd->xvec;
  146. }
  147.  
  148.  
  149. static boolean
  150. b_out_mkobject (abfd)
  151.      bfd *abfd;
  152. {
  153.   PTR  rawptr;
  154.  
  155.   bfd_error = system_call_error;
  156.  
  157.   /* Use an intermediate variable for clarity */
  158.   rawptr = (PTR) zalloc (sizeof (struct aoutdata) + sizeof (struct internal_exec));
  159.  
  160.   if (rawptr == (PTR)NULL) {
  161.     bfd_error = no_memory;
  162.     return false;
  163.   }
  164.  
  165.   set_tdata(abfd, (struct aoutdata *) rawptr);
  166.   exec_hdr (abfd) = (struct internal_exec *) ( (char*)rawptr + sizeof (struct aoutdata));
  167.  
  168.   /* For simplicity's sake we just make all the sections right here. */
  169.   obj_textsec (abfd) = (asection *)NULL;
  170.   obj_datasec (abfd) = (asection *)NULL;
  171.   obj_bsssec (abfd) = (asection *)NULL;
  172.  
  173.   bfd_make_section (abfd, ".text");
  174.   bfd_make_section (abfd, ".data");
  175.   bfd_make_section (abfd, ".bss");
  176.  
  177.   return true;
  178. }
  179.  
  180. static boolean
  181. b_out_write_object_contents (abfd)
  182.      bfd *abfd;
  183. {
  184.   struct internal_exec swapped_hdr;
  185.  
  186.   exec_hdr (abfd)->a_magic = BMAGIC;
  187.  
  188.   exec_hdr (abfd)->a_text = obj_textsec (abfd)->size;
  189.   exec_hdr (abfd)->a_data = obj_datasec (abfd)->size;
  190.   exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->size;
  191.   exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
  192.   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
  193.   exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) *
  194.                                sizeof (struct relocation_info));
  195.   exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) *
  196.                                sizeof (struct relocation_info));
  197.  
  198.   exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
  199.   exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
  200.   exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
  201.  
  202.   exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
  203.   exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
  204.  
  205.   /* FIXME, turn the header into bytes here, to avoid problems with
  206.      sizes and alignments of its fields.  */
  207.   swapped_hdr = *exec_hdr(abfd);
  208.   swap_exec_header (abfd, &swapped_hdr);
  209.  
  210.   bfd_seek (abfd, 0L, SEEK_SET);
  211.   bfd_write ((PTR) &swapped_hdr, 1, sizeof (struct internal_exec), abfd);
  212.  
  213.   /* Now write out reloc info, followed by syms and strings */
  214.   if (bfd_get_symcount (abfd) != 0) 
  215.     {
  216.       bfd_seek (abfd,
  217.         (long)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET);
  218.  
  219.       aout_32_write_syms (abfd);
  220.  
  221.       bfd_seek (abfd,    (long)(N_TROFF(*exec_hdr(abfd))), SEEK_SET);
  222.  
  223.       if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
  224.       bfd_seek (abfd, (long)(N_DROFF(*exec_hdr(abfd))), SEEK_SET);
  225.  
  226.       if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
  227.     }
  228.   return true;
  229. }
  230.  
  231. static void
  232. swap_exec_header (abfd, execp)
  233.      bfd *abfd;
  234.      struct internal_exec *execp;
  235. {
  236. #define swapme(field)    field = bfd_h_get_32 (abfd, (unsigned char *)&field);
  237.   swapme (execp->a_magic);
  238.   swapme (execp->a_text);
  239.   swapme (execp->a_data);
  240.   swapme (execp->a_bss);
  241.   swapme (execp->a_syms);
  242.   swapme (execp->a_entry);
  243.   swapme (execp->a_trsize);
  244.   swapme (execp->a_drsize);
  245.   swapme (execp->a_tload);
  246.   swapme (execp->a_dload);
  247.   /* talign, dalign, and balign are one-byte fields and don't swap.  */
  248. #undef swapme
  249. }
  250.  
  251. /** Some reloc hackery */
  252.  
  253. #define CALLS     0x66003800    /* Template for 'calls' instruction    */
  254. #define BAL     0x0b000000    /* Template for 'bal' instruction    */
  255. #define BAL_MASK 0x00ffffff
  256.  
  257. static bfd_reloc_status_enum_type 
  258. callj_callback(abfd, reloc_entry, symbol_in, data, input_section)
  259. bfd *abfd;
  260. arelent *reloc_entry;
  261. asymbol *symbol_in;
  262. unsigned char *data;
  263. asection *input_section;
  264. {
  265.   int  word = bfd_get_32(abfd, data+reloc_entry->address);
  266.   aout_symbol_type  *symbol = aout_symbol(symbol_in);
  267.  
  268.   if (IS_OTHER(symbol->other)) {
  269.     /* Call to a system procedure - replace code with system
  270.        procedure number 
  271.        */
  272.  
  273.     word = CALLS | (symbol->other - 1);
  274.     bfd_put_32(abfd, word,  data+reloc_entry->address); /* replace */
  275.     return bfd_reloc_ok;
  276.   }
  277.     
  278.   if (IS_CALLNAME(symbol->other)) {
  279.     aout_symbol_type *balsym = symbol+1;
  280.     /* The next symbol should be an N_BALNAME */
  281.     BFD_ASSERT(IS_BALNAME(balsym->other));
  282.  
  283.     /* We are calling a leaf - so replace the call instruction
  284.        with a bal */
  285.   
  286.     word = BAL |
  287.       (((word & BAL_MASK) +
  288.      balsym->symbol.section->output_offset +
  289.      balsym->symbol.section->output_section->vma+
  290.     balsym->symbol.value + reloc_entry->addend - 
  291.     ( input_section->output_section->vma + input_section->output_offset))
  292.        & BAL_MASK);
  293.  
  294.     bfd_put_32(abfd, word,  data+reloc_entry->address); /* replace */
  295.     return bfd_reloc_ok;
  296.   }
  297.   return bfd_reloc_continue;
  298.  
  299. }
  300. /* type rshift size  bitsize      pcrel    bitpos  absolute overflow check*/
  301.  
  302.  
  303. static reloc_howto_type howto_reloc_callj =
  304. HOWTO( 3, 0, 2, 24, true, 0, true, true, callj_callback,"callj", true, 0x00ffffff, 0x00ffffff,false);
  305. static  reloc_howto_type howto_reloc_abs32 =
  306. HOWTO(1, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false);
  307. static reloc_howto_type howto_reloc_pcrel24 =
  308. HOWTO(2, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
  309.  
  310. /* Allocate enough room for all the reloc entries, plus pointers to them all */
  311.  
  312. static boolean
  313. b_out_slurp_reloc_table (abfd, asect, symbols)
  314.      bfd *abfd;
  315.      sec_ptr asect;
  316.      asymbol **symbols;
  317. {
  318.   unsigned int count;
  319.   size_t  reloc_size;
  320.   struct relocation_info *relocs;
  321.   arelent *reloc_cache;
  322.  
  323.   if (asect->relocation) return true;
  324.   if (!aout_32_slurp_symbol_table (abfd)) return false;
  325.  
  326.   if (asect == obj_datasec (abfd)) {
  327.     reloc_size = exec_hdr(abfd)->a_drsize;
  328.     goto doit;
  329.   }
  330.  
  331.   if (asect == obj_textsec (abfd)) {
  332.     reloc_size = exec_hdr(abfd)->a_trsize;
  333.     goto doit;
  334.   }
  335.  
  336.   bfd_error = invalid_operation;
  337.   return false;
  338.  
  339.  doit:
  340.   bfd_seek (abfd, (long)(asect->rel_filepos), SEEK_SET);
  341.   count = reloc_size / sizeof (struct relocation_info);
  342.  
  343.   relocs = (struct relocation_info *) malloc (reloc_size);
  344.   if (!relocs) {
  345.     bfd_error = no_memory;
  346.     return false;
  347.   }
  348.   reloc_cache = (arelent *) malloc ((count+1) * sizeof (arelent));
  349.   if (!reloc_cache) {
  350.     free ((char*)relocs);
  351.     bfd_error = no_memory;
  352.     return false;
  353.   }
  354.  
  355.   if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
  356.     bfd_error = system_call_error;
  357.     free (reloc_cache);
  358.     free (relocs);
  359.     return false;
  360.   }
  361.  
  362.   {
  363.     register struct relocation_info *rptr = relocs;
  364.     unsigned int counter = 0;
  365.     arelent *cache_ptr = reloc_cache;
  366.     int extern_mask, pcrel_mask, callj_mask;
  367.   
  368.     if (abfd->xvec->header_byteorder_big_p) {
  369.       /* Big-endian bit field allocation order */
  370.       pcrel_mask  = 0x80;
  371.       extern_mask = 0x10;
  372.       callj_mask  = 0x02;
  373.     } else {
  374.       /* Little-endian bit field allocation order */
  375.       pcrel_mask  = 0x01;
  376.       extern_mask = 0x08;
  377.       callj_mask  = 0x40;
  378.     }
  379.  
  380.     for (; counter < count; counter++, rptr++, cache_ptr++) 
  381.       {
  382.     unsigned char *raw = (unsigned char *)rptr;
  383.     unsigned int symnum;
  384.     cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
  385.      if (abfd->xvec->header_byteorder_big_p) {
  386.       symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
  387.      } else {
  388.       symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
  389.     }
  390.  
  391.     if (raw[7] & extern_mask) {
  392.       /* If this is set then the r_index is a index into the symbol table;
  393.        * if the bit is not set then r_index contains a section map.
  394.        * We either fill in the sym entry with a pointer to the symbol,
  395.        * or point to the correct section
  396.        */
  397.       cache_ptr->sym_ptr_ptr = symbols + symnum;
  398.       cache_ptr->addend = 0;
  399.       cache_ptr->section = (asection*)NULL;
  400.     } else {
  401.       /* In a.out symbols are relative to the beginning of the
  402.        * file rather than sections ?
  403.        * (look in translate_from_native_sym_flags)
  404.        * The reloc entry addend has added to it the offset into the
  405.        * file of the data, so subtract the base to make the reloc
  406.        * section relative */
  407.       cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
  408.       switch (symnum) {
  409.       case N_TEXT:
  410.       case N_TEXT | N_EXT:
  411.         cache_ptr->section = obj_textsec(abfd);
  412.         cache_ptr->addend = -obj_textsec(abfd)->vma;
  413.         break;
  414.       case N_DATA:
  415.       case N_DATA | N_EXT:
  416.         cache_ptr->section = obj_datasec(abfd);
  417.         cache_ptr->addend = - obj_datasec(abfd)->vma;
  418.         break;
  419.       case N_BSS:
  420.       case N_BSS | N_EXT:
  421.         cache_ptr->section = obj_bsssec(abfd);
  422.         cache_ptr->addend =  - obj_bsssec(abfd)->vma;
  423.         break;
  424.       case N_ABS:
  425.       case N_ABS | N_EXT:
  426.         BFD_ASSERT(0);
  427.         break;
  428.       default:
  429.         BFD_ASSERT(0);
  430.         break;
  431.       }
  432.     
  433.     }
  434.  
  435.      /* The i960 only has a few relocation types:
  436.        abs 32-bit and pcrel 24bit.   Except for callj's!  */
  437.     if (raw[7] & callj_mask)
  438.       cache_ptr->howto = &howto_reloc_callj;
  439.     else if ( raw[7] & pcrel_mask)
  440.       cache_ptr->howto = &howto_reloc_pcrel24;
  441.     else
  442.       cache_ptr->howto = &howto_reloc_abs32;
  443.       }
  444.   }
  445.  
  446.   free (relocs);
  447.   asect->relocation = reloc_cache;
  448.   asect->reloc_count = count;
  449.   return true;
  450. }
  451.  
  452.  
  453. static boolean
  454. b_out_squirt_out_relocs (abfd, section)
  455.      bfd *abfd;
  456.      asection *section;
  457. {
  458.   arelent **generic;
  459.  
  460.   unsigned int count = section->reloc_count;
  461.   struct relocation_info *native, *natptr;
  462.   size_t natsize = count * sizeof (struct relocation_info);
  463.   int extern_mask, pcrel_mask,  len_2, callj_mask;
  464.   if (count == 0) return true;
  465.   generic   = section->orelocation;
  466.   native = ((struct relocation_info *) malloc (natsize));
  467.   if (!native) {
  468.     bfd_error = no_memory;
  469.     return false;
  470.   }
  471.  
  472.    if (abfd->xvec->header_byteorder_big_p) {
  473.        /* Big-endian bit field allocation order */
  474.        pcrel_mask  = 0x80;
  475.        extern_mask = 0x10;
  476.        len_2       = 0x40;
  477.       callj_mask  = 0x02;
  478.    } else {
  479.        /* Little-endian bit field allocation order */
  480.        pcrel_mask  = 0x01;
  481.        extern_mask = 0x08;
  482.        len_2       = 0x04;
  483.       callj_mask  = 0x40;
  484.    }
  485.  
  486.   for (natptr = native; count > 0; --count, ++natptr, ++generic) 
  487.     {
  488.       arelent *g = *generic;
  489.       unsigned char *raw = (unsigned char *)natptr;
  490.       unsigned int symnum;
  491.  
  492.       bfd_h_put_32(abfd, g->address, raw);  
  493.       /* Find a type in the output format which matches the input howto - 
  494.        * at the moment we assume input format == output format FIXME!!
  495.        */
  496.       /* FIXME:  Need callj stuff here, and to check the howto entries to
  497.      be sure they are real for this architecture.  */
  498.       if (g->howto== &howto_reloc_callj) {
  499.     raw[7] = callj_mask + pcrel_mask + len_2;
  500.       }
  501.       else if (g->howto == &howto_reloc_pcrel24) {
  502.     raw[7] = pcrel_mask +len_2;
  503.       }
  504.       else {
  505.     raw[7] = len_2;
  506.       }
  507.       if (g->sym_ptr_ptr != (asymbol **)NULL) 
  508.     {
  509.       /* name clobbered by aout_write_syms to be symbol index*/
  510.       if ((*(g->sym_ptr_ptr))->section) {
  511.         /* replace the section offset into the addent */
  512.         g->addend += (*(g->sym_ptr_ptr))->section->vma ;
  513.       }
  514.       symnum = stoi((*(g->sym_ptr_ptr))->name);
  515.       raw[7] |= extern_mask;
  516.       BFD_ASSERT(g->addend == 0);
  517.     }
  518.       else {
  519.     if (g->section == (asection *)NULL) {
  520.       symnum = N_ABS;
  521.       BFD_ASSERT(0);
  522.     }
  523.     else  if(g->section->output_section == obj_textsec(abfd)) {
  524.       symnum = N_TEXT;
  525.        BFD_ASSERT(g->addend + obj_textsec(abfd)->vma == 0);
  526.  
  527.     }
  528.     else if (g->section->output_section == obj_datasec(abfd)) {
  529.       symnum  = N_DATA;
  530.        BFD_ASSERT(g->addend + obj_datasec(abfd)->vma == 0);
  531.  
  532.     }
  533.     else if (g->section->output_section == obj_bsssec(abfd)) {
  534.       symnum = N_BSS;
  535.        BFD_ASSERT(g->addend + obj_bsssec(abfd)->vma == 0);
  536.  
  537.  
  538.     }
  539.     else {
  540.       BFD_ASSERT(0);
  541.     }
  542.       }
  543.       if (abfd->xvec->header_byteorder_big_p) {
  544.     raw[4] = (unsigned char) (symnum >> 16);
  545.     raw[5] = (unsigned char) (symnum >>  8);
  546.     raw[6] = (unsigned char) (symnum      );
  547.       } else {
  548.     raw[6] = (unsigned char) (symnum >> 16);
  549.     raw[5] = (unsigned char) (symnum >>  8);
  550.     raw[4] = (unsigned char) (symnum      );
  551.       }  
  552.     }
  553.  
  554.   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
  555.     free((PTR)native);
  556.     return false;
  557.   }
  558.   free ((PTR)native);
  559.  
  560.   return true;
  561. }
  562.  
  563. /* This is stupid.  This function should be a boolean predicate */
  564. static unsigned int
  565. b_out_canonicalize_reloc (abfd, section, relptr, symbols)
  566.      bfd *abfd;
  567.      sec_ptr section;
  568.      arelent **relptr;
  569.      asymbol **symbols;
  570. {
  571.   arelent *tblptr = section->relocation;
  572.   unsigned int count = 0;
  573.  
  574.  if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0;
  575.   tblptr = section->relocation;
  576.  if (!tblptr) return 0;
  577.  
  578.   for (; count++ < section->reloc_count;)
  579.     *relptr++ = tblptr++;
  580.  
  581.   *relptr = 0;
  582.  
  583.   return section->reloc_count;
  584. }
  585.  
  586. static unsigned int
  587. b_out_get_reloc_upper_bound (abfd, asect)
  588.      bfd *abfd;
  589.      sec_ptr asect;
  590. {
  591.   if (bfd_get_format (abfd) != bfd_object) {
  592.     bfd_error = invalid_operation;
  593.     return 0;
  594.   }
  595.  
  596.   if (asect == obj_datasec (abfd))
  597.     return (sizeof (arelent *) *
  598.         ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
  599.          +1));
  600.  
  601.   if (asect == obj_textsec (abfd))
  602.     return (sizeof (arelent *) *
  603.         ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
  604.          +1));
  605.  
  606.   bfd_error = invalid_operation;
  607.   return 0;
  608. }
  609.  
  610. static boolean
  611. b_out_set_section_contents (abfd, section, location, offset, count)
  612.      bfd *abfd;
  613.      sec_ptr section;
  614.      unsigned char *location;
  615.      file_ptr offset;
  616.       int count;
  617. {
  618.   if (abfd->output_has_begun == false) { /* set by bfd.c handler */
  619.     if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*||
  620.         (obj_textsec (abfd)->size == 0) || (obj_datasec (abfd)->size == 0)*/) {
  621.       bfd_error = invalid_operation;
  622.       return false;
  623.     }
  624.  
  625.     obj_textsec (abfd)->filepos = sizeof(struct internal_exec);
  626.     obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos 
  627.                                 +  obj_textsec (abfd)->size;
  628.  
  629.   }
  630.   /* regardless, once we know what we're doing, we might as well get going */
  631.   bfd_seek (abfd, section->filepos + offset, SEEK_SET);
  632.  
  633.   if (count != 0) {
  634.     return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
  635.   }
  636.   return false;
  637. }
  638.  
  639. static boolean
  640. b_out_set_arch_mach (abfd, arch, machine)
  641.      bfd *abfd;
  642.      enum bfd_architecture arch;
  643.      unsigned long machine;
  644. {
  645.   abfd->obj_arch = arch;
  646.   abfd->obj_machine = machine;
  647.   if (arch == bfd_arch_unknown)    /* Unknown machine arch is OK */
  648.     return true;
  649.   if (arch == bfd_arch_i960)    /* i960 default is OK */
  650.     switch (machine) {
  651.     case bfd_mach_i960_core:
  652.     case bfd_mach_i960_kb_sb:
  653.     case bfd_mach_i960_mc:
  654.     case bfd_mach_i960_xa:
  655.     case bfd_mach_i960_ca:
  656.     case bfd_mach_i960_ka_sa:
  657.     case 0:
  658.       return true;
  659.     default:
  660.       return false;
  661.     }
  662.  
  663.   return false;
  664. }
  665.  
  666. static int 
  667. DEFUN(b_out_sizeof_headers,(abfd, exec),
  668.       bfd *abfd AND
  669.       boolean exec)
  670. {
  671.   return sizeof(struct internal_exec);
  672. }
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680. /* Build the transfer vectors for Big and Little-Endian B.OUT files.  */
  681.  
  682. /* We don't have core files.  */
  683. #define    aout_32_core_file_failing_command    _bfd_dummy_core_file_failing_command
  684. #define    aout_32_core_file_failing_signal    _bfd_dummy_core_file_failing_signal
  685. #define    aout_32_core_file_matches_executable_p    \
  686.                 _bfd_dummy_core_file_matches_executable_p
  687.  
  688. /* We use BSD-Unix generic archive files.  */
  689. #define    aout_32_openr_next_archived_file    bfd_generic_openr_next_archived_file
  690. #define    aout_32_generic_stat_arch_elt    bfd_generic_stat_arch_elt
  691. #define    aout_32_slurp_armap        bfd_slurp_bsd_armap
  692. #define    aout_32_slurp_extended_name_table    bfd_true
  693. #define    aout_32_write_armap        bsd_write_armap
  694. #define    aout_32_truncate_arname        bfd_bsd_truncate_arname
  695.  
  696. /* We override these routines from the usual a.out file routines.  */
  697. #define    aout_32_canonicalize_reloc        b_out_canonicalize_reloc
  698. #define    aout_32_get_reloc_upper_bound    b_out_get_reloc_upper_bound
  699. #define    aout_32_set_section_contents    b_out_set_section_contents
  700. #define    aout_32_set_arch_mach        b_out_set_arch_mach
  701. #define    aout_32_sizeof_headers        b_out_sizeof_headers
  702.  
  703. #define aout_32_bfd_debug_info_start        bfd_void
  704. #define aout_32_bfd_debug_info_end        bfd_void
  705. #define aout_32_bfd_debug_info_accumulate    (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
  706.  
  707.  
  708. bfd_target b_out_vec_big_host =
  709. {
  710.   "b.out.big",            /* name */
  711.   bfd_target_aout_flavour_enum,
  712.   false,            /* data byte order is little */
  713.   true,                /* hdr byte order is big */
  714.   (HAS_RELOC | EXEC_P |        /* object flags */
  715.    HAS_LINENO | HAS_DEBUG |
  716.    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
  717.   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  718.   ' ',                /* ar_pad_char */
  719.   16,                /* ar_max_namelen */
  720.      2,                /* minumum alignment power */
  721.  
  722. _do_getl64, _do_putl64,  _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
  723. _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
  724.     {_bfd_dummy_target, b_out_big_object_p, /* bfd_check_format */
  725.        bfd_generic_archive_p, _bfd_dummy_target},
  726.     {bfd_false, b_out_mkobject,    /* bfd_set_format */
  727.        _bfd_generic_mkarchive, bfd_false},
  728.     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
  729.        _bfd_write_archive_contents, bfd_false},
  730.  
  731.   JUMP_TABLE(aout_32)
  732. };
  733.  
  734.  
  735. bfd_target b_out_vec_little_host =
  736. {
  737.   "b.out.little",        /* name */
  738.   bfd_target_aout_flavour_enum,
  739.   false,            /* data byte order is little */
  740.   false,            /* header byte order is little */
  741.   (HAS_RELOC | EXEC_P |        /* object flags */
  742.    HAS_LINENO | HAS_DEBUG |
  743.    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
  744.   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  745.   ' ',                /* ar_pad_char */
  746.   16,                /* ar_max_namelen */
  747.      2,                /* minum align */
  748. _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
  749. _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
  750.      
  751.     {_bfd_dummy_target, b_out_little_object_p, /* bfd_check_format */
  752.        bfd_generic_archive_p, _bfd_dummy_target},
  753.     {bfd_false, b_out_mkobject,    /* bfd_set_format */
  754.        _bfd_generic_mkarchive, bfd_false},
  755.     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
  756.        _bfd_write_archive_contents, bfd_false},
  757.   JUMP_TABLE(aout_32)
  758. };
  759.  
  760.